#include <Arduino.h>
#include <Servo.h>
#include <EEPROM.h>
#include "LightClient.h"

const int serverPort = 8081;

LightClient lightClient;
MsgHeader msgHeader;

Servo servo;

extern "C" {
struct range {
    uint8_t up;
    uint8_t down;
};

struct range servo_range = {
        70, 160
};
}

void setup() {
    Serial.begin(115200);
    while (!Serial) {}
    Serial.println("read flash ");
    // 尝试从flash中读取保存的范围
    EEPROM.begin(512);
    // 第一位表示是否存值,默认0xff
    if (EEPROM.read(0) == 1) {
        Serial.printf("has value");
        EEPROM.get(1, servo_range);
        Serial.printf("up and down in eeprom is: %d %d \n", servo_range.up, servo_range.down);
    }
    // sg90
    servo.attach(SERVO_PIN, 500, 2500);
    ConnectInfo connectInfo;
    connectInfo.ssid = WIFI_SSID;
    connectInfo.passphrase = WIFI_PASSWORD;
    connectInfo.serverPort = serverPort;
    connectInfo.attrCount = 2;
    connectInfo.devAttr = "version:1.0\n"
                          "devType:ServoSwitch\n";

#ifdef SERVER_HOST
    connectInfo.host = SERVER_HOST;
#else
    connectInfo.host = nullptr;
#endif
    connectInfo.userName = USER_NAME;
    connectInfo.passwd = PASS_WD;
    lightClient.connectServer(&connectInfo);

}

void debugOp() {
    Serial.println("rec:" + lightClient.readStringUntil('\n'));
}

void lightSwitch() {
    int action = lightClient.readInt('\n');
    servo.write(action == 0 ? servo_range.up : servo_range.down);
    delay(240);
    servo.write(90);
}

void setRange() {
    int range = lightClient.readInt('\n');
    if (range < 0 || range > 180) {
        return;
    }
    servo_range.up = range;
    servo_range.down = 180 - range;
    EEPROM.write(0, 1);
    EEPROM.put(1, servo_range);
    EEPROM.commit();
}

void setLocation() {
    int range = lightClient.readInt('\n');
    if (range < 0 || range > 180) {
        return;
    }
    servo.write(range);
}

void (*opTab[4])() = {debugOp, lightSwitch, setRange, setLocation};

void loop() {

    int result = lightClient.readMsgHeader(&msgHeader);

    if (result == MSG_FAILED) {
        return;
    }
    int opCode = msgHeader.opCode;
    Serial.printf("cmdId:%d,opCode:%d\n", msgHeader.cmdIdVal, opCode);
    if (opCode > 3 || opCode < 0) {
        return;
    }
    opTab[opCode]();
}
